package com.medistat.security;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.context.SecurityContextHolder;

import com.medistat.model.User;
import com.medistat.persistance.service.interfaces.PersistanceService;
import com.medistat.services.Credentials;
import com.medistat.services.UserContext;

public class CustomAuthenticationManagerImpl implements CustomAuthenticationManager {

	private PersistanceService persistanceService;
	private UserContext userContext;

	@Autowired
	public void setPersistanceService(PersistanceService persistanceService) {
		this.persistanceService = persistanceService;
	}
	
	@Autowired
	public void setUserContext(UserContext userContext) {
		this.userContext = userContext;
	}

	public Authentication authenticate(Authentication auth) throws AuthenticationException {		
		String username = auth.getName();
		String password = auth.getCredentials().toString();
		return checkUser(username, password);
	}

	private Authentication checkUser(String username, String password) {
		User user = null;
		try {
			user = persistanceService.getUser(username, Decoder.getMD5_Base64(password));
		} catch (Exception e) {
			throw new BadCredentialsException("User does not exists!");
		}
		if (user==null) {
			throw new BadCredentialsException("User or password does not exists!");
		}

		Credentials credentials = new Credentials(user.getUsername(), password);
		userContext.setCredentials(credentials);
		return new UsernamePasswordAuthenticationToken(username, password, Arrays.asList(new GrantedAuthorityImpl("ROLE_ADMIN")));

	}
	
	public void reAuthenticate(String username, String newPassword) {
		Authentication authentication = checkUser(username, newPassword);
		SecurityContextHolder.getContext().setAuthentication(authentication);
	}

	//Authorities are not in used yet. Login user has "ROLE_ADMIN" role at the moment.
	public Collection<GrantedAuthority> getAuthorities(Integer access) {
		// Create a list of grants for this user
		List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>(2);

		// All users are granted with ROLE_USER access
		// Therefore this user gets a ROLE_USER by default
		authList.add(new GrantedAuthorityImpl("ROLE_USER"));

		// Check if this user has admin access
		// We interpret Integer(1) as an admin user
		if (access.compareTo(1) == 0) {
			// User has admin access
			authList.add(new GrantedAuthorityImpl("ROLE_ADMIN"));
		}

		// Return list of granted authorities
		return authList;
	}
}
